package edu.psu.collegerecommendationhelper.algorithm;

import java.util.ArrayList;
import java.util.List;

import weka.core.Instance;
import weka.core.Instances;
import weka.core.neighboursearch.NearestNeighbourSearch;
import edu.psu.collegerecommendationhelper.model.RecommendationListing;



/**
 * 
 * @author cbarone
 *
 * The RecommendationResults class takes the transformed user input and runs it against the
 * trained model. A list of recommendations is returned.
 * 
 */
public class RecommendationResults {

	//Variable that sets the K for 
	//the number of Instances to return in nearest
	//neighbor search.
	int MAX_COLLEGE_RETURN = 20;
	
	//Class constructor.
	public RecommendationResults() {
		
	}

	
	//This function returns a list of recommendations based on the 
	//algorithm's nearest neighbor search.
	public List<RecommendationListing> createRecommendationsFromNearestNeighborSearch(Instances data) {
		List<RecommendationListing> results = new ArrayList<RecommendationListing>();
		NearestNeighbourSearch algorithm = null;
		WekaToolUtility wtu = new WekaToolUtility();
		
		try {
			algorithm = wtu.generateModelAlgorithm();
		} catch (Exception e) {
			e.printStackTrace();
		}

		int rslt = bestFitCollege(algorithm, data);
			
		List<Integer> nxtRslt = topCollegesList(algorithm, data);
		
		System.out.println(nxtRslt);
		
		RecommendationListing rl = new RecommendationListing();
		RecommendationListing newRl = new RecommendationListing();

		rl.setAddress("State College, PA");
		rl.setName("Penn State");
		rl.setURL("www.psu.edu");

		newRl.getAddress();
		newRl.getName();
		newRl.getURL();

		results.add(newRl);

		return results;
	}

	
	//This function build's a list of recommendation results from the 
	//nearest neighbor algorithm.
	private List<RecommendationListing> buildCollegeListFromLookup(List<Integer> data) {
		List<RecommendationListing> results = new ArrayList<RecommendationListing>();
		
		return results;
	}
	
	
	//This function returns the top result from the nearest neighbor algorithm
	//for the test Instances.
	private int bestFitCollege (NearestNeighbourSearch algo, Instances data) {			
        Instance rslt = null;
		try {
			rslt = algo.nearestNeighbour(data.firstInstance());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
        return (int)rslt.value(0);
	}

	
	//This function returns a list of MAX_COLLEGE_RETURN for the 
	//nearest neighbor algorithm and the provided test Instances.
	private List<Integer> topCollegesList (NearestNeighbourSearch algo, Instances data) {
		List<Integer> resultsList = new ArrayList<Integer>();
        Instances rslt = null;
        
		try {
			rslt = algo.kNearestNeighbours(data.firstInstance(), MAX_COLLEGE_RETURN);
		} catch (Exception e) {
			e.printStackTrace();
		}
				
		for (int i=0; i<MAX_COLLEGE_RETURN; i++)
		{
			resultsList.add((int)rslt.instance(i).value(0));
		}
		  		
        return resultsList;
	}
	
	//This function runs a model evaluation on the user's data.
	public boolean testUserSelectionAgainstLearnermodel(Instances userTestData) {
        boolean testRslt = false;
        WekaToolUtility wtu = new WekaToolUtility();
		
        try {
        	testRslt = wtu.evaluateTestData(userTestData);
		} catch (Exception e) {
			e.printStackTrace();
		}
        
        return testRslt;
	}
}